package it.unibo.deis.lia.mmhc.fnm;

//Classe che genera ed invia il primo messaggio di ricerca(searchservice)
import it.unibo.deis.lia.mmhc.ServiceGui;
import it.unibo.deis.lia.mmhc.spm.Service;

import java.io.ObjectOutputStream;

import java.net.Socket;

import java.util.Vector;

public class ClientServiceSearch extends Thread {

	private FindNeighbours neighboursFinder;
	public static Vector<String> neighbours = new Vector<String>();
	// private DatagramSocket socket;
	private String service;
	private int hopNumber;

	public ClientServiceSearch(String service, int hopNumber) {
		neighboursFinder = FindNeighbours.getInstance();
		this.service = service;
		this.hopNumber = hopNumber;

		// try {
		// socket=new DatagramSocket(2401);
		// }catch(BindException e){
		// try {
		// socket=new DatagramSocket(2401);
		// }catch (Exception f) {
		// // TODO: handle exception
		// }
		// }
		// catch (SocketException e) {
		// System.err.println("Impossibile aprire la socket di invio");
		// e.printStackTrace();
		// }
	}

	public void send(int hop, String string) {
		hop--;
		SearchService message = new SearchService(hop, string);
		searchService(message);
	}

	public static void serviceTrovato(FindedService findedService) {
		// farà qualcosa quando lo ha trovato ovvero deve aprire la mitica path
		// tcp forse sarà
		// conveniente metterlo in un altro package in cui si avranno le varie
		// connessioni tcp aperte
		// con i vari servizi ritrovabili
		ServiceGui.addFindedService(findedService);

		Service risposta = (Service) findedService.getOgg();
		System.err.println("Trovato il mitico servizio " + risposta.getName()
				+ " in " + risposta.getFornitore() + " sulla porta "
				+ risposta.getPort());

	}

	private void searchService(SearchService message) {
		// MessageObject message=new MessageObject(hopToLive,o);
		neighbours = neighboursFinder.getNeighbourgs();

		// try {
		//			
		// socket.setSoTimeout(3000);
		// ByteArrayOutputStream fos = new ByteArrayOutputStream();
		// ObjectOutputStream oos = new ObjectOutputStream(fos);
		// oos.writeObject(message);
		// oos.close();
		//
		// // end serialization
		// byte[] buff = new byte[1024];
		// byte[] sendByte = fos.toByteArray();
		// for (int i = 0; i < neighbours.size(); i++) {
		// int t = 3;
		// boolean ackricevuto = false;
		// while (t > 0 && !ackricevuto) {
		// try {
		// DatagramPacket packet = new DatagramPacket(sendByte,
		// sendByte.length, InetAddress.getByName(neighbours
		// .elementAt(i)), 2401);
		// socket.send(packet);
		// packet = new DatagramPacket(buff, buff.length);
		//				
		//
		// socket.receive(packet);
		// String received = new String(packet.getData(), 0,
		// packet.getLength());
		// if (received.equalsIgnoreCase("ack")){
		//							
		//						
		// ackricevuto = true;
		// System.err.println("Invio richiesta ricevuta correttamente");
		// }
		//
		// } catch (SocketTimeoutException e) {
		// t--;
		// }
		// }
		// }
		// socket.setSoTimeout(0);
		//
		// } catch (Exception e) {
		// System.err.println("Impossibile fare il flooding");
		// e.printStackTrace();
		// }

		// tcp
		try {
			for (int i = 0; i < neighbours.size(); i++) {
				int attempts = 5;
				Socket out = null;
				do {
					try {
						out = new Socket(neighbours.elementAt(i), 2401);
					} catch (Exception e) {
						Thread.sleep(1500);
						attempts--;
						if (attempts == 0)
							throw e;
					}
				} while (attempts > 0 && out == null);
				ObjectOutputStream oos = new ObjectOutputStream(out
						.getOutputStream());
				oos.flush();
				oos.writeObject(message);
				System.err.println("Inviato ricerca di servizio");
				oos.flush();
				out.close();
			}
		} catch (Exception e) {
			System.err.println("Qualche errore nell'invio del oggetto " + e);
		}
	}

	public void run() {

		try {
			// while (true) {
			if (hopNumber > 0) {
				// String neig="I vicini sono: ";
				// if(!neighbours.isEmpty()||neighbours!=null){
				// for(int i=0;i<neighbours.size();i++){
				// neig+=neighbours.elementAt(i)+" ";
				//				
				// }}
				// System.out.println(neig);
				send(hopNumber, service);
			}
			// sleep(10000);
			// }
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	// Main usato solo in fase di test
	public static void main(String argv[]) throws Exception {
		ClientServiceSearch sender = new ClientServiceSearch("marco", 1);
		while (true) {
			String neig = "I vicini sono: ";
			if (!neighbours.isEmpty() || neighbours != null) {
				for (int i = 0; i < neighbours.size(); i++) {
					neig += neighbours.elementAt(i) + " ";

				}
			}
			System.out.println(neig);
			sender.send(1, "marco");

			Thread.sleep(10000);
		}

	}

}
